﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using FizzBuzzCore;
using FizzBuzzCore.Interfaces;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace FizzBuzzTest
{
    /// <summary>
    /// Tests for FizzBuzz
    /// </summary>
    [TestClass]
    public class FizzBuzzUnitTest
    {
        /// <summary>
        /// Tests to see if an <exception cref="ApplicationException">exception</exception> is thrown when lower limit is greater than upper limit
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ApplicationException))]
        public void LimitTest()
        {
            //Arrange
            IFizzBuzz fizzBuzz = FizzBuzz.NewObject();
            fizzBuzz.LowerLimit = 15;
            fizzBuzz.UpperLimit = 12;

            //Act
            IList<string> testList = fizzBuzz.FizzBuzzList;
        }

        /// <summary>
        /// Tests to verify the business rules for FizzBuzz
        /// </summary>
        [TestMethod]
        public void VerifyLogic()
        {
            //Arrange
            IList<string> testItems = new List<string>
                                          {
                                              "Fizz",       //-3
                                              "-2",         //-2
                                              "-1",         //-1
                                              "FizzBuzz",   //0
                                              "1",          //1
                                              "2",          //2
                                              "Fizz",       //3
                                              "4",          //4
                                              "Buzz",       //5
                                              "Fizz",       //6
                                              "7",          //7
                                              "8",          //8
                                              "Fizz",       //9
                                              "Buzz",       //10
                                              "11",         //11
                                              "Fizz",       //12
                                              "13",         //13
                                              "14",         //14
                                              "FizzBuzz",   //15
                                              "16"          //16
                                          };
            //Act
            IFizzBuzz fizzBuzz = FizzBuzz.NewObject();
            fizzBuzz.LowerLimit = -3;
            fizzBuzz.UpperLimit = 16;

            //Assert
            Assert.AreEqual(20, fizzBuzz.FizzBuzzList.Count);
            for (int index = 0; index < testItems.Count; index++)
            {
                Assert.AreEqual(testItems[index], fizzBuzz.FizzBuzzList[index]);
            }

            //Arrange
            testItems = new List<string>
                            {
                                              "1",          //1
                                              "2",          //2
                                              "Fizz",       //3
                                              "4",          //4
                                              "Buzz",       //5
                                              "Fizz",       //6
                                              "7",          //7
                                              "8",          //8
                                              "Fizz",       //9
                                              "Buzz",       //10
                                              "11",         //11
                                              "Fizz",       //12
                                              "13",         //13
                                              "14",         //14
                                              "FizzBuzz",   //15
                            };
            //Act
            fizzBuzz.LowerLimit = 1;
            fizzBuzz.UpperLimit = 15;

            //Assert
            Assert.AreEqual(15, fizzBuzz.FizzBuzzList.Count);
            for (int index = 0; index < testItems.Count; index++)
            {
                Assert.AreEqual(testItems[index], fizzBuzz.FizzBuzzList[index]);
            }

        }

        [TestMethod]
        public void VerifyIsDirtyLogic()
        {
            //Arrange
            IFizzBuzz ifizzBuzz = FizzBuzz.NewObject();
            FizzBuzz fizzBuzz;

            if (ifizzBuzz is FizzBuzz)
            {
                fizzBuzz = ifizzBuzz as FizzBuzz;
            }
            else
            {
                throw new Exception("Invalid Fizzbuzz object");
            }

            //Assert
            Assert.AreEqual(false, fizzBuzz.IsLowerLimitDirty);
            Assert.AreEqual(false, fizzBuzz.IsUpperLimitDirty);

            //Arrange
            fizzBuzz.UpperLimit = 40;
            fizzBuzz.LowerLimit = 34;

            //Assert
            Assert.AreEqual(true, fizzBuzz.IsLowerLimitDirty);
            Assert.AreEqual(true, fizzBuzz.IsUpperLimitDirty);

            //Act
            var list = fizzBuzz.FizzBuzzList;

            //Assert
            Assert.AreEqual(false, fizzBuzz.IsLowerLimitDirty);
            Assert.AreEqual(false, fizzBuzz.IsUpperLimitDirty);
        }

        [TestMethod]
        public void VerifySetLimitMessage()
        {
            //Arrange
            IFizzBuzz fizzBuzz = FizzBuzz.NewObject();

            //Act
            var list = fizzBuzz.FizzBuzzList;

            //Assert
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(FizzBuzzResource.setLowerUpperLimitText, list.First());
        }
    }
}
